package com.louis.security;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.RegexUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
import org.springframework.stereotype.Component;

import com.louis.dao.GeneralDao;

import javax.annotation.Resource;
import java.util.*;

@Component("secureResourceFilterInvocationDefinitionSource")
public class UserDefindInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource, InitializingBean {

	private UrlMatcher										urlMatcher;
	private boolean											useAntPath	= true;
	private boolean											lowercase	= true;
	@Resource(name = "generalDao")
	private GeneralDao										generalDao;
	private static Map<String, Collection<ConfigAttribute>>	resources	= new HashMap<String, Collection<ConfigAttribute>>();

	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		FilterInvocation filterInvocation = (FilterInvocation) object;
		Iterator<String> iterator = resources.keySet().iterator();
		if (urlMatcher == null) {
			if (useAntPath) {
				urlMatcher = new AntUrlPathMatcher(lowercase);
			} else {
				urlMatcher = new RegexUrlPathMatcher();
				((RegexUrlPathMatcher) urlMatcher).setRequiresLowerCaseUrl(lowercase);
			}
		}
		while (iterator.hasNext()) {
			String uri = iterator.next();
			String requestUrl = filterInvocation.getRequestUrl();
			if (urlMatcher.pathMatchesUrl(uri, requestUrl)) {
				return resources.get(uri);
			}
		}
		return null;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		List<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
		for (Collection<ConfigAttribute> attributes: resources.values()) {
			configAttributes.addAll(attributes);
		}
		return configAttributes;
	}

	public boolean supports(Class<?> clazz) {
		return true;
	}

	/**
	 * @return the urlMatcher
	 */
	public UrlMatcher getUrlMatcher() {
		return this.urlMatcher;
	}

	/**
	 * @param urlMatcher
	 *            the urlMatcher to set
	 */
	public void setUrlMatcher(UrlMatcher urlMatcher) {
		this.urlMatcher = urlMatcher;
	}

	/**
	 * @return the useAntPath
	 */
	public boolean isUseAntPath() {
		return this.useAntPath;
	}

	/**
	 * @param useAntPath
	 *            the useAntPath to set
	 */
	public void setUseAntPath(boolean useAntPath) {
		this.useAntPath = useAntPath;
	}

	/**
	 * @return the lowercase
	 */
	public boolean isLowercase() {
		return this.lowercase;
	}

	/**
	 * @param lowercase
	 *            the lowercase to set
	 */
	public void setLowercase(boolean lowercase) {
		this.lowercase = lowercase;
	}

	/**
	 * @return the generalDao
	 */
	public GeneralDao getGeneralDao() {
		return this.generalDao;
	}

	/**
	 * @param generalDao
	 *            the generalDao to set
	 */
	public void setGeneralDao(GeneralDao generalDao) {
		this.generalDao = generalDao;
	}

	/**
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {

	}

}